package com.hunttown.mes.manage.controller._mes;

import com.hunttown.mes.common.OperateCode;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.rpc.domain.*;
import com.hunttown.mes.rpc.domain.enums.mes.pck.NumberRuleEnum;
import com.hunttown.mes.rpc.domain.query.MesProducePackageDTOQuery;
import com.hunttown.mes.rpc.domain.query.MesProducePassStationDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.utils.*;
import com.hunttown.mes.manage.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * created by wangjunfu on 2022-06-07 08:15:22
 */
@Controller
@RequestMapping(value = "/mes/produce-package-rule")
public class MesProducePackageRuleController {

    private final static Logger logger = LoggerFactory.getLogger(MesProducePackageRuleController.class);

    private final MesProducePackageRuleManageService mesProducePackageRuleService;
    private final MesProducePackageManageService mesProducePackageService;
    private final MesProducePassStationManageService mesProducePassStationService;
    private final MesProducePassStationDetailManageService mesProducePassStationDetailService;
    private final MesProduceOrderManageService mesProduceOrderService;
    private final AnalysisManageManageService manageService;

    @Autowired
    public MesProducePackageRuleController(MesProducePackageRuleManageService mesProducePackageRuleService, MesProducePackageManageService mesProducePackageService, MesProducePassStationManageService mesProducePassStationService, MesProducePassStationDetailManageService mesProducePassStationDetailService, MesProduceOrderManageService mesProduceOrderService, AnalysisManageManageService manageService) {
        this.mesProducePackageRuleService = mesProducePackageRuleService;
        this.mesProducePackageService = mesProducePackageService;
        this.mesProducePassStationService = mesProducePassStationService;
        this.mesProducePassStationDetailService = mesProducePassStationDetailService;
        this.mesProduceOrderService = mesProduceOrderService;
        this.manageService = manageService;
    }

    //region 编辑&保存

    /**
     * 编辑
     *
     * @param model model模型
     * @param id    主键id
     * @return model
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Model model, Integer id, Integer produceId) {
        id = (id == null ? 0 : id);

        if (produceId == null || produceId <= 0) {
            throw new RuntimeException("未查询到生产订单信息");
        }

        //获取生产订单信息
        MesProduceOrderDTO produceObj = mesProduceOrderService.getById(produceId);
        if (produceObj == null) {
            throw new RuntimeException("未查询到生产订单信息");
        }
        model.addAttribute("produceObj", produceObj);

        MesProducePackageRuleDTO obj = mesProducePackageRuleService.getByProduceId(produceId);

        if (obj != null) {
            obj.setProduceName(produceObj.getOrderName());

            //region 打包明细
            MesProducePackageDTOQuery packageQuery = new MesProducePackageDTOQuery();
            packageQuery.setProduceId(produceId);
            packageQuery.setPackageStatus(1);
            packageQuery.setStopFlag(0);
            Page<MesProducePackageDTO> packagePage = mesProducePackageService.getForPage(packageQuery);
            for (MesProducePackageDTO item : packagePage.getItems()) {
                if (item.getPackageType() == 2) {
                    item.setPackageTypeName("组合包");

                    if (StringUtils.isNotBlank(item.getOriginPkg())) { //来自于哪几个包
                        List<Integer> oriPkgIds = FormatUtils.commaToList_Integer(item.getOriginPkg());

                        List<String> oriPkgNames = new ArrayList<>();
                        for (Integer pkg : oriPkgIds) {
                            MesProducePackageDTO dto = mesProducePackageService.getById(pkg);
                            oriPkgNames.add(dto.getPackageName());
                        }
                        item.setOriginPkgName(String.join(",", oriPkgNames));
                    }
                }
                if (item.getPackageType() == 3) {
                    item.setPackageTypeName("拆包");

                    if (StringUtils.isNotBlank(item.getOriginPkg())) { //从那个包来
                        MesProducePackageDTO dto = mesProducePackageService.getById(Integer.parseInt(item.getOriginPkg()));
                        item.setOriginPkgName(dto.getPackageName());
                    }
                }
            }
            model.addAttribute("packageList", packagePage.getItems());
            //endregion

        } else {
            obj = new MesProducePackageRuleDTO();
            obj.setId(0);
            obj.setProduceId(produceObj.getId());
            obj.setProduceName(produceObj.getOrderName());
            obj.setTotalCount(produceObj.getEstimateCount());
            obj.setPackageCount(0);
            obj.setAvgCount(0);
            obj.setStartNumber(1);
            obj.setEndNumber(produceObj.getEstimateCount());

            //SN编号规则：{年月日6位}{订单编号5位}{尾数自增2位}
            obj.setSnPre(GeneralUtils.GenDateSeries(produceId, 5));
        }
        model.addAttribute("Obj", obj);

        //编码规则
        model.addAttribute("numberRuleList", NumberRuleEnum.getEnumList());

        //如果已经有过站记录，则不可再编辑；子单也不可以编辑
        int canEdit = 0;

        if (produceObj.getParentId() == 0) {
            //[1].查询已过站记录
            MesProducePassStationDTOQuery passProcessQuery = new MesProducePassStationDTOQuery();
            passProcessQuery.setProduceId(produceId);
            passProcessQuery.setStopFlag(0);
            Page<MesProducePassStationDTO> passProcessPage = mesProducePassStationService.getForPage(passProcessQuery);

            //[2].仅有一条的情况下
            if (passProcessPage.getItems().size() == 1) {
                MesProducePassStationDTO passStationObj = passProcessPage.getItems().get(0);
                if (passStationObj == null || passStationObj.getPassStatus() == 0) {
                    canEdit = 1;
                }
            }

            //[3].一条也没有的情况下
            if (passProcessPage.getItems().size() == 0) {
                canEdit = 1;
            }
        }

        model.addAttribute("canEdit", canEdit);

        return "mes/produce-package-rule/edit";
    }

    /**
     * 保存 ajax异步
     *
     * @param request sevelet请求
     * @param objDTO  实体类
     * @return json
     */
    @RequestMapping(value = "/saveEdit", method = RequestMethod.POST)
    @ResponseBody
    public String saveEditNotify(HttpServletRequest request, MesProducePackageRuleDTO objDTO) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

            if (objDTO.getId() == null || objDTO.getId() <= 0) {
                //新增
                //设置初始值
                objDTO.setAdminId(curr_obj.getId());
                objDTO.setCreateTime(new Date());
                objDTO.setStopFlag(0);
                objDTO.setDeleteFlag(0);
                objDTO = mesProducePackageRuleService.insert(objDTO);

                if (objDTO == null || objDTO.getId() <= 0) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }

            } else {
                //更新
                //将不需要更新的字段设置为NULL
                Boolean isNext = mesProducePackageRuleService.updateInfoById(objDTO);

                if (!isNext) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //region [01].打包明细表
            String[] f_id = request.getParameterValues("f_id");
            String[] f_packagename = request.getParameterValues("f_packagename");
            String[] f_totalcount = request.getParameterValues("f_totalcount");
            String[] f_startnumber = request.getParameterValues("f_startnumber");
            String[] f_endnumber = request.getParameterValues("f_endnumber");
            String[] f_sncode = request.getParameterValues("f_sncode");

            //1.获取已保存的打包明细
            MesProducePackageDTOQuery packageHistoryQuery = new MesProducePackageDTOQuery();
            packageHistoryQuery.setProduceId(objDTO.getProduceId());
            packageHistoryQuery.setPackageStatus(1);
            packageHistoryQuery.setStopFlag(0);
            packageHistoryQuery.setPageSize(100);
            Page<MesProducePackageDTO> packageHistoryPage = mesProducePackageService.getForPage(packageHistoryQuery);

            //首先搞一个onlysign，以前有就从库里取，没有就生成
            String onlysign = GetRandomUtils.GetRandom(12);

            //这里要改一种思路了，因为重新生成包的时候，f_id会被清空
            //以SN码作为唯一判断依据吧
            List<String> snList = new ArrayList<>();
            for (MesProducePackageDTO item : packageHistoryPage.getItems()) {
                snList.add(item.getSnCode().trim());
                onlysign = item.getOnlySign();
            }

            //2. 保存到数据库
            if (f_id != null && f_id.length > 0) {

                List<String> newPackageIds = new ArrayList<>(); //提交上来的，已保存过的SN码
                MesProducePackageDTOQuery insert;

                for (int i = 0; i < f_id.length; i++) {

                    String _sncode = f_sncode[i].trim();
                    if (StringUtils.isBlank(_sncode)) {
                        continue;
                    }

                    insert = new MesProducePackageDTOQuery();
                    insert.setProduceId(objDTO.getProduceId());
                    insert.setPackageName(f_packagename[i]);
                    insert.setPackageType(1);
                    insert.setTotalCount(Integer.parseInt(f_totalcount[i]));
                    insert.setStartNumber(Integer.parseInt(f_startnumber[i]));
                    insert.setEndNumber(Integer.parseInt(f_endnumber[i]));
                    insert.setSnCode(_sncode);
                    insert.setPackageStatus(1);
                    insert.setOnlySign(onlysign);
                    insert.setAdminId(curr_obj.getId());
                    insert.setCreateTime(new Date());
                    insert.setStopFlag(0);
                    insert.setDeleteFlag(0);

                    //更新或插入
                    if (snList.contains(_sncode)) {
                        //更新
                        newPackageIds.add(_sncode);
                        insert.setW_snCode(_sncode);
                        mesProducePackageService.updateInfoByQuery(insert);

                    } else {
                        //插入
                        mesProducePackageService.insert(insert);
                    }
                }

                //3.不存在新列表中的则表示已经删除了
                for (MesProducePackageDTO item : packageHistoryPage.getItems()) {
                    if (!newPackageIds.contains(item.getSnCode())) {
                        mesProducePackageService.delete(item.getId());
                    }
                }
            }
            //endregion

            //region [02].更新生产订单表中 计算数量
            MesProduceOrderDTO update = new MesProduceOrderDTO();
            update.setId(objDTO.getProduceId());
            update.setRealCount(objDTO.getTotalCount());
            mesProduceOrderService.updateInfoById(update);
            //endregion

            //操作成功 结果返回
            map = OperateCode.CompositionResult(map, 1);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 条形码打印（由于标签打印格式问题，不使用此方法）
    @RequestMapping(value = "/snPrint", method = RequestMethod.GET)
    public String snPrint(Model model, Integer produceId) {

        if (produceId == null || produceId <= 0) {
            throw new RuntimeException("未查询到生产订单信息");
        }

        //获取生产订单信息
        MesProduceOrderDTO produceObj = mesProduceOrderService.getById(produceId);
        if (produceObj == null) {
            throw new RuntimeException("未查询到生产订单信息");
        }
        model.addAttribute("produceObj", produceObj);

        MesProducePackageDTOQuery packageQuery = new MesProducePackageDTOQuery();
        packageQuery.setProduceId(produceId);
        packageQuery.setStopFlag(0);
        Page<MesProducePackageDTO> packagePage = mesProducePackageService.getForPage(packageQuery);
        model.addAttribute("packageList", packagePage.getItems());

        return "mes/produce-package-rule/sn-print";
    }
    //endregion

    //region 拆包
    @RequestMapping(value = "/unpackTheBox", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> unpackTheBox(HttpServletRequest request, String unpackageIds, Integer firstPkgCount, Integer produceId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        //做一些验证
        if (StringUtils.isBlank(unpackageIds) && !unpackageIds.equals(",")) {
            map.put("returnMessage", "缺少参数");
            return map;
        }

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

        //取出主包
        unpackageIds = unpackageIds.replace(",", "");
        MesProducePackageDTO mainPkg = mesProducePackageService.getById(Integer.parseInt(unpackageIds));
        if (firstPkgCount > mainPkg.getTotalCount()) {
            map.put("returnMessage", "第1个包数量不能大于主包数量");
            return map;
        }

        //加权平均，计算真实的第一个包数量
        int pkg1_count = firstPkgCount;
        int pkg2_count = mainPkg.getTotalCount() - firstPkgCount;

        //查出主包最新过站的良品数，做加权平均，否则下一次过站时总过站数不对
        MesProducePassStationDetailDTO lastPastPkg = mesProducePassStationDetailService.getByProducePkg(produceId, mainPkg.getId());
        if (lastPastPkg != null) {
            pkg1_count = Math.round(((float) firstPkgCount / (float) mainPkg.getTotalCount()) * lastPastPkg.getGoodCount());
            pkg2_count = lastPastPkg.getGoodCount() - pkg1_count;
        }

        //第1个包
        String newsSnCode = genNewestSnCode(mainPkg.getOnlySign());

        MesProducePackageDTO unpack_one = new MesProducePackageDTO();
        unpack_one.setId(0);
        unpack_one.setProduceId(mainPkg.getProduceId());
        unpack_one.setPackageName("包" + Integer.parseInt(newsSnCode.substring(newsSnCode.length() - 2)));
        unpack_one.setPackageType(3);
        unpack_one.setTotalCount(pkg1_count);
        unpack_one.setStartNumber(mainPkg.getStartNumber());
        unpack_one.setEndNumber(mainPkg.getStartNumber() + firstPkgCount - 1);
        unpack_one.setSnCode(newsSnCode);
        unpack_one.setOriginPkg(unpackageIds);
        unpack_one.setPackageStatus(1);
        unpack_one.setOnlySign(mainPkg.getOnlySign());
        unpack_one.setAdminId(curr_obj.getId());
        unpack_one.setCreateTime(new Date());
        unpack_one.setStopFlag(0);
        unpack_one.setDeleteFlag(0);
        unpack_one = mesProducePackageService.insert(unpack_one);

        //第2个包
        newsSnCode = genNewestSnCode(mainPkg.getOnlySign());

        MesProducePackageDTO unpack_two = new MesProducePackageDTO();
        unpack_two.setId(0);
        unpack_two.setProduceId(mainPkg.getProduceId());
        unpack_two.setPackageName("包" + Integer.parseInt(newsSnCode.substring(newsSnCode.length() - 2)));
        unpack_two.setPackageType(3);
        unpack_two.setTotalCount(pkg2_count);
        unpack_two.setStartNumber(mainPkg.getStartNumber() + firstPkgCount);
        unpack_two.setEndNumber(mainPkg.getEndNumber());
        unpack_two.setSnCode(newsSnCode);
        unpack_two.setOriginPkg(unpackageIds);
        unpack_two.setPackageStatus(1);
        unpack_two.setOnlySign(mainPkg.getOnlySign());
        unpack_two.setAdminId(curr_obj.getId());
        unpack_two.setCreateTime(new Date());
        unpack_two.setStopFlag(0);
        unpack_two.setDeleteFlag(0);
        unpack_two = mesProducePackageService.insert(unpack_two);

        //更新主包
        mainPkg.setToPkg(unpack_one.getId() + "," + unpack_two.getId());
        mainPkg.setPackageStatus(0);
        mesProducePackageService.updateInfoById(mainPkg);

        map.put("returnCode", 1);
        map.put("returnMessage", "拆包成功");
        return map;
    }
    //endregion

    //region 合包
    @RequestMapping(value = "/packageTheBox", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> packageTheBox(HttpServletRequest request, String unpackageIds, Integer produceId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        //做一些验证
        if (StringUtils.isBlank(unpackageIds)) {
            map.put("returnMessage", "缺少参数");
            return map;
        }

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

        List<MesProducePackageDTO> oriPkgList = new ArrayList<>();

        MesProducePackageDTO defaultDTO = new MesProducePackageDTO();

        int startNumber = 0;
        int endNumber = 0;
        int totalCount = 0;

        //循环取出所有包
        List<Integer> pkgIds = FormatUtils.commaToList_Integer(unpackageIds);
        for (Integer pkg : pkgIds) {
            MesProducePackageDTO dto = mesProducePackageService.getById(pkg);
            oriPkgList.add(dto);

            //包总数不能是原包累加，应该是最新过站良品数累加
            MesProducePassStationDetailDTO lastPastPkg = mesProducePassStationDetailService.getByProducePkg(produceId, dto.getId());
            if (lastPastPkg != null) {
                totalCount += lastPastPkg.getGoodCount();
            } else {
                totalCount += dto.getTotalCount();
            }

            defaultDTO = dto;

            if (startNumber == 0) {
                startNumber = dto.getStartNumber();
            } else {
                startNumber = startNumber > dto.getStartNumber() ? dto.getStartNumber() : startNumber;
            }

            if (endNumber == 0) {
                endNumber = dto.getEndNumber();
            } else {
                endNumber = endNumber > dto.getEndNumber() ? endNumber : dto.getEndNumber();
            }
        }

        String newsSnCode = genNewestSnCode(defaultDTO.getOnlySign());

        //插入组合包
        MesProducePackageDTO joinPkg = new MesProducePackageDTO();
        joinPkg.setId(0);
        joinPkg.setProduceId(defaultDTO.getProduceId());
        joinPkg.setPackageName("包" + Integer.parseInt(newsSnCode.substring(newsSnCode.length() - 2)));
        joinPkg.setPackageType(2);
        joinPkg.setTotalCount(totalCount);
        joinPkg.setStartNumber(startNumber);
        joinPkg.setEndNumber(endNumber);
        joinPkg.setSnCode(newsSnCode);
        joinPkg.setOriginPkg(unpackageIds);
        joinPkg.setPackageStatus(1);
        joinPkg.setOnlySign(defaultDTO.getOnlySign());
        joinPkg.setAdminId(curr_obj.getId());
        joinPkg.setCreateTime(new Date());
        joinPkg.setStopFlag(0);
        joinPkg.setDeleteFlag(0);
        joinPkg = mesProducePackageService.insert(joinPkg);

        //更新来源包
        for (MesProducePackageDTO item : oriPkgList) {
            item.setToPkg(joinPkg.getId() + "");
            item.setPackageStatus(0);
            mesProducePackageService.updateInfoById(item);
        }

        map.put("returnCode", 1);
        map.put("returnMessage", "合包成功");
        return map;
    }
    //endregion

    //region 生成最新的sn码
    private String genNewestSnCode(String onlysign) {
        MesProducePackageDTOQuery packageQuery = new MesProducePackageDTOQuery();
        //这里为什么不使用produceId？因为要考虑到拆单以后的情况
        packageQuery.setOnlySign(onlysign);
        packageQuery.setStopFlag(0);
        packageQuery.setOrderBy("order by id desc");
        MesProducePackageDTO packageDTO = mesProducePackageService.getByQuery(packageQuery);

        String sn = "";
        if (packageDTO == null) {
            return sn;
        }

        String _presn = packageDTO.getSnCode().substring(0, packageDTO.getSnCode().length() - 2);
        String _fixsn = packageDTO.getSnCode().substring(packageDTO.getSnCode().length() - 2);
        sn = _presn + StringUtils.padLeft(Integer.parseInt(_fixsn) + 1, 2);

        return sn;
    }
    //endregion
}